package app;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import net.miginfocom.layout.CC;
import net.miginfocom.swing.MigLayout;
import KUtilities.KLogger;
import KUtilities.KPanel;
import KUtilities.KSpringOld;
import KUtilities.KSwing;
import KUtilities.KTextArea;
import KUtilities.KTextField;
import Websites.SMS440;
import Websites.SMSService;
import Websites.Way2SMS;
import Websites._160By2;

public class SMSPanel extends JPanel {
	private static final long serialVersionUID = 1L;
	private boolean autoLogin=true;
	private KLogger logger;
	private KTextField numbers;
	@SuppressWarnings("rawtypes")
	private JComboBox service;
	private Action loginLogoutAction;
	private SMSService way2sms,sms440,_160by2;
	private JLayeredPane main;
	private KSpringOld mainSpring;
	private JPanel disabler;
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public SMSPanel(JLayeredPane main,KSpringOld mainSpring){
		this.main=main;
		this.mainSpring=mainSpring;
		disabler=KSwing.createDisablerPanel(450, 350);
		setOpaque(false);
		
		final JLabel serviceLabel,numbersLabel,smsLabel;
		final JButton loginLogout;
		final JButton compress,send;
		final KTextArea smsArea;
		final JScrollPane smsPane;
		final JLabel charsLabel;
		
		KeyListener enterKey=new KeyAdapter(){
			public void keyPressed(KeyEvent ke)
			{
				if(ke.getKeyCode()==KeyEvent.VK_ENTER){
					Object source=ke.getSource(); 
					if(source instanceof JButton)
						((JButton)source).doClick();
					else if(source instanceof JCheckBox)
						((JCheckBox)source).setSelected(!((JCheckBox)source).isSelected());
				}
			}
		};
		
		numbersLabel=new JLabel("Number:");
		numbers=new KTextField();

		loginLogoutAction=new AbstractAction("Login"){
			private static final long serialVersionUID = 1L;
			{
				putValue(MNEMONIC_KEY, KeyEvent.VK_L);
			}
			public void actionPerformed(ActionEvent ae) {
				if(getValue(NAME).equals("Login")){
					showLogin();
				}
				else if(getService().logout())
					putValue(NAME,"Login");
			}
		};
		loginLogout=new JButton(loginLogoutAction);
		loginLogout.addKeyListener(enterKey);

		serviceLabel=new JLabel("Service:");
		
		service=new JComboBox();
		service.addItem("Way2SMS (140 Chars)");
		service.addItem("160by2 (140 Chars)");
		service.addItem("SMS440 (440 Chars)");
		
		service.addItemListener(new ItemListener(){
			public void itemStateChanged(ItemEvent ie){
				if(isLoggedIn()){
					loginLogout.getAction().putValue(Action.NAME, "Logout");
				}else{
					loginLogout.getAction().putValue(Action.NAME, "Login");
				}
			}
		});		
		
		smsLabel=new JLabel("Message:");
		charsLabel=new JLabel("0 Charecters = 1 Message");
		
		smsArea=new KTextArea(){
			private static final long serialVersionUID = 1L;
			{
				Thread t=new Thread(){
					public void run(){
						try {
							BufferedReader langReader=new BufferedReader(new FileReader("lib"+File.separator+"SMSLang.dat"));
							String langLine=langReader.readLine();
							String temp[];
							HashMap<String,String> langMap=new HashMap<String,String>();
							while(langLine!=null){
								temp=langLine.split(" - ");
								if(temp[0]!=null&&temp[1]!=null){
									langMap.put(temp[0], temp[1]);
								}
								langLine=langReader.readLine();
							}
							enableAutoComplete(langMap,true);
						} catch (Exception e) {}
					}
				};
				t.start();
			}
		};
		
		smsArea.setWrapStyleWord(true);
		smsArea.setLineWrap(true);
		Action focusNext=new AbstractAction(){
			private static final long serialVersionUID = 1L;
			public void actionPerformed(ActionEvent ae){
				((JComponent)ae.getSource()).transferFocus();
			}
		};
		Action focusPrevious=new AbstractAction(){
			private static final long serialVersionUID = 1L;
			public void actionPerformed(ActionEvent ae){
				((JComponent)ae.getSource()).transferFocusBackward();
			}
		};
		smsArea.registerKeyboardAction(focusNext, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), JComponent.WHEN_FOCUSED);
		smsArea.registerKeyboardAction(focusPrevious, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_MASK), JComponent.WHEN_FOCUSED);
		smsArea.getDocument().addDocumentListener(new DocumentListener(){
			public void changedUpdate(DocumentEvent arg0) {
				int len=smsArea.getText().length();
				String temp=len+" Charecters = "+(len/(getService().getMaxChar()+1)+1)+" Message";
				charsLabel.setText(temp);
			}

			public void insertUpdate(DocumentEvent arg0) {
				int len=smsArea.getText().length();
				String temp=len+" Charecters = "+(len/(getService().getMaxChar()+1)+1)+" Message";
				charsLabel.setText(temp);
			}

			public void removeUpdate(DocumentEvent arg0) {
				int len=smsArea.getText().length();
				String temp=len+" Charecters = "+(len/(getService().getMaxChar()+1)+1)+" Message";
				charsLabel.setText(temp);
			}
			
		});
		
		smsPane=new JScrollPane(smsArea);
								
		send=new JButton("Send");
		send.setMnemonic('S');
		send.addKeyListener(enterKey);
		send.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent ae){
				if(isLoggedIn()){
					String phNumbers=numbers.getText();
					String message=smsArea.getText();
					if(!phNumbers.endsWith(";"))
						phNumbers+=";";
					getService().sendMessages(phNumbers,message);
					smsArea.setText("");
					smsArea.requestFocus();
				}else{
					logger.log(getServiceName()+": "+"You should be logged in to Send Message");
				}
			}
		});
		
		compress=new JButton("Compress Words");
		compress.setMnemonic('C');
		compress.addKeyListener(enterKey);
		compress.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent ae){
				logger.log(getServiceName()+": "+"Not Yet Implemented");
			}
		});
		
		logger=new KLogger();
		
		logger.getLogger().getDocument().addDocumentListener(new DocumentListener(){
			public void changedUpdate(DocumentEvent arg0) {
			}

			public void insertUpdate(DocumentEvent arg0) {
				if(!isLoggedIn()){
					loginLogout.getAction().putValue(Action.NAME, "Login");
				}
			}

			public void removeUpdate(DocumentEvent arg0) {
			}
			
		});
		
		setLayout(new MigLayout());
		add(serviceLabel);
		add(service,new CC().split());
		add(loginLogout,"wrap");
		add(numbersLabel);
		add(numbers,new CC().grow().wrap().span());
		add(smsLabel,new CC());
		add(smsPane,new CC().grow().span().wrap().height("125").width("300"));
		add(charsLabel,new CC().skip(1).wrap());
		add(send,new CC().skip(1).split());
		add(compress,"wrap");
		add(logger,new CC().skip(1).grow().span().wrap().height("150"));
		
		/*KSpringLayout smsSpring=new KSpringLayout(this);
		
		smsSpring.addRow(serviceLabel,service,loginLogout);
		smsSpring.addRow(numbersLabel,numbers);
		smsSpring.addRow(smsLabel,smsPane);
		smsSpring.addRow(charsLabel);
		smsSpring.addRow(send,compress);
		smsSpring.addRow(logger);
		
		smsSpring.setHeight(smsPane, 130);
		smsSpring.setHeight(logger, 130);
		smsSpring.alignLeft(smsLabel,logger);
		smsSpring.alignLeft(service,numbers,smsPane,charsLabel,send);
		smsSpring.alignRight(serviceLabel,numbersLabel,smsLabel);
		smsSpring.alignRight(loginLogout,numbers,smsPane,logger);
		smsSpring.pack();
		*/
	}
	
	/**
	 * Returns the text field holding numbers
	 * @return text field holding numbers
	 */
	public KTextField getNumbersField(){
		return numbers;
	}
	
	/**
	 * Returns The Selected SMS Service
	 * @return The Selected SMS Service
	 */
	public SMSService getService(){
		String selected=service.getSelectedItem().toString().toLowerCase();
		if(selected.contains("way2sms")){
			if(way2sms==null)
				way2sms=new Way2SMS(logger);
			return way2sms;
		}else if(selected.contains("sms440")){
			if(sms440==null)
				sms440=new SMS440(logger);
			return sms440;
		}else if(selected.contains("160by2")){
			if(_160by2==null)
				_160by2=new _160By2(logger);
			return _160by2;
		}else
			return null;
	}
	
	/**
	 * Is the user logged in
	 * @return true if logged in, false otherwise
	 */
	private boolean isLoggedIn(){
		return getService().isLoggedIn();
	}
	
	/**
	 * Get the Name of the Service 
	 * @return name of the service
	 */
	private String getServiceName(){
		return getService().getServiceName();
	}
	
	/**
	 * Get the login Action Object
	 * @return login action
	 */
	public Action getLoginLogoutAction(){
		return loginLogoutAction;
	}
		
	Timer timer,t;
	ActionListener timerAction;
	public void showLogin() {
		final JLabel userLabel,passLabel,status,status2;
		final JTextField user;
		final JPasswordField pass;
		final JButton login,cancel;
		final JCheckBox save;
		final KPanel loginPanel;
		
		loginPanel=new KPanel();
		loginPanel.setOpaque(false);
		userLabel=new JLabel(getServiceName()+" Username:");
		passLabel=new JLabel(getServiceName()+" Password:");
		userLabel.setForeground(Color.green);
		passLabel.setForeground(Color.green);
		user=new JTextField(13);
		pass=new JPasswordField(13);
		pass.setEchoChar('?');
		login=new JButton("Login");
		cancel=new JButton("Cancel");
		login.setMnemonic('L');
		cancel.setMnemonic('C');
		save=new JCheckBox("Save");
		save.setForeground(Color.green);
		status=new JLabel("<html><br/></html>");
		status2=new JLabel("<html><br/></html>");
		status.setForeground(Color.green);
		status2.setForeground(Color.green);
		
		KSpringOld loginSpring=new KSpringOld(loginPanel);
		loginSpring.add(userLabel,user,passLabel,pass,login,cancel,save,status,status2);
		loginSpring.setHGap(5, loginPanel,userLabel,user,loginPanel);
		loginSpring.setVGap(5, loginPanel,userLabel,passLabel,save,status,status2,loginPanel);
		loginSpring.setHGap(5, save,login,cancel);
		loginSpring.alignHorizontal(userLabel,user);
		loginSpring.alignHorizontal(passLabel,pass);
		loginSpring.alignHorizontal(save,login,cancel);
		loginSpring.alignVertical(userLabel,passLabel);
		loginSpring.alignRight(userLabel,save);
		loginSpring.alignVertical(user,pass);
		loginSpring.alignLeft(pass,login);
		loginSpring.alignRight(pass,cancel);

		mainSpring.addToCenter(KSwing.disabler,loginPanel);
		KSwing.disable(main);
		loginPanel.zoomIn(200);
		timerAction=new ActionListener(){
			public void actionPerformed(ActionEvent ae)
			{
				if(!loginPanel.isAlive())
				{
					timer.stop();
					KSwing.enable(loginPanel);
					user.requestFocus();
				}
			}
		};
		timer=new Timer(30,timerAction);
		timer.start();
		ActionListener loginAction=new ActionListener(){
			public void actionPerformed(ActionEvent ae){
				final String password=new String(pass.getPassword());
				final String username=user.getText().trim();
							
				String statusText[]=getService().login(username, password).split("\n");
				status.setText(statusText[0]);
				if(statusText.length==2)
				status2.setText(statusText[1]);
				if(status.getText().toLowerCase().equals("login successful")){
					KSwing.enable(main);
					KSwing.disable(loginPanel);
					loginLogoutAction.putValue(Action.NAME,"Logout");
					loginPanel.zoomOut(200);
					timerAction=new ActionListener(){
						public void actionPerformed(ActionEvent ae)
						{
							if(!loginPanel.isAlive())
							{
								timer.stop();
								timer=null;
								timerAction=null;
								mainSpring.remove(disabler,loginPanel);
								numbers.requestFocus();
							}
						}
					};
					timer=new Timer(30,timerAction);
					timer.start();
					File userFile=new File("data"+File.separator+getServiceName()+".dat");
					if(save.isSelected()){
							User serviceUser=new User(username,password);
							serviceUser.save(userFile);
					}else if(userFile.exists())
						userFile.delete();
				}
			}
		};
		login.addActionListener(loginAction);
	
		cancel.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent ae){
				KSwing.enable(main);
				KSwing.disable(loginPanel);
				loginPanel.zoomOut(200);
				timerAction=new ActionListener(){
					public void actionPerformed(ActionEvent ae)
					{
						if(!loginPanel.isAlive())
						{
							timer.stop();
							timer=null;
							timerAction=null;
							mainSpring.remove(disabler,loginPanel);	
						}
					}
				};
				timer=new Timer(30,timerAction);
				timer.start();
			}
		});
		
		
		KeyListener keys=new KeyAdapter(){
			public void keyPressed(KeyEvent ke)
			{
				if(ke.getKeyCode()==KeyEvent.VK_ENTER){
					login.doClick();
				}else if(ke.getKeyCode()==KeyEvent.VK_ESCAPE){
					cancel.doClick();
				}
			}
		};
		
		KeyListener enterKey=new KeyAdapter(){
			public void keyPressed(KeyEvent ke)
			{
				if(ke.getKeyCode()==KeyEvent.VK_ENTER){
					Object source=ke.getSource(); 
					if(source instanceof JButton)
						((JButton)source).doClick();
					else if(source instanceof JCheckBox)
						((JCheckBox)source).setSelected(!((JCheckBox)source).isSelected());
				}
			}
		};
		user.addKeyListener(keys);
		pass.addKeyListener(keys);
		login.addKeyListener(enterKey);
		cancel.addKeyListener(enterKey);
		save.addKeyListener(enterKey);
		
		File userFile=new File("data"+File.separator+getServiceName()+".dat");
		if(userFile.exists()){
			User serviceUser=new User();
			serviceUser.load(userFile);
			user.setText(serviceUser.getUsername());
			pass.setText(serviceUser.getPassword());
			save.setSelected(true);
			ActionListener botAction=new ActionListener(){
				public void actionPerformed(ActionEvent ae){
					if(autoLogin){
						login.doClick();
						autoLogin=false;
					}
					t.stop();
				}
			};
			t=new Timer(250,botAction);
			t.setInitialDelay(750);
			t.start();
		}
	}	
}
